import React, { useRef, useEffect } from "react";
import {
    MeshNormalMaterial, Mesh, DoubleSide, Object3D, SplineCurve, Vector2, Line, BufferGeometry, LineBasicMaterial,
    Matrix4, Vector3, MeshBasicMaterial, SphereGeometry, MeshPhongMaterial, Color, PointLight, Group, Object3DEventMap, PerspectiveCamera, DirectionalLight, Plane, PlaneGeometry,
} from 'three';
import Stage from '../component/Stage';
import Tank from '../component/Mesh/Tank';
import { GUI } from 'dat.gui'
import Axis from "../component/Axis";
import PlayerController from '../component/PlayerController'

const stage = new Stage(window.innerWidth, window.innerHeight, new Vector3(0, 20, 0), new Vector3(1, 1, 2));
const { scene, renderer } = stage;

renderer.shadowMap.enabled = true;//开启投影

const camera = createCamera()
camera.position.set(16, 8, 20);
stage.setCamera(camera, new Vector3(0, 0, 0));



//#region light
const light = new DirectionalLight(new Color(1, 1, 1), 1);
light.position.set(0, 20, 0);
stage.add(light, 'light');
light.castShadow = true;//映射投影
light.shadow.mapSize.set(2048, 2048);//投影贴图精度

const d = 50;
light.shadow.camera.left = -d;
light.shadow.camera.right = d;
light.shadow.camera.top = d;
light.shadow.camera.bottom = -d;
light.shadow.camera.near = 1;
light.shadow.camera.far = d;

//补光
const light1 = new DirectionalLight(new Color(1, 1, 1), 1);
light1.position.set(1, 2, 4);
stage.add(light1, 'light');
//#endregion

//#region 地面
const groundGeo = new PlaneGeometry(50, 50);
const groundMat = new MeshPhongMaterial({ color: new Color(0.6, 0.6, 0.6), side: DoubleSide, });
const ground = new Mesh(groundGeo, groundMat);
ground.receiveShadow = true;//接受投影
ground.rotation.x = 90 * Math.PI / 180;
stage.add(ground, 'object');
//#endregion

const tank = new Tank();
stage.add(tank, 'object');
// stage.setCamera(tank.getCamera(), tank._lookAt);
const playerController = new PlayerController(tank);

//目标点
const target = new Mesh(new SphereGeometry(0.2, 4, 4), new MeshPhongMaterial({ color: new Color(0, 1, 0), flatShading: true }));//逐三角面作色
target.position.copy(new Vector3(-3, 5, -3));
stage.add(target, 'object');

//获取路径
const curve = new SplineCurve([
    new Vector2(-6, 5),
    new Vector2(-6, -4),
    new Vector2(8, 0),
    new Vector2(3, 8),
    new Vector2(-6, 12),
    new Vector2(-6, 5),
])
const points = curve.getPoints(50);

const splineObj = new Line(new BufferGeometry().setFromPoints(points), new LineBasicMaterial({ color: new Color(1, 0, 0) }));
splineObj.rotateX(90 * Math.PI / 180);
splineObj.position.y = 0.1;
stage.add(splineObj, 'object');


//切换相机
const gui = new GUI({ autoPlace: false });
const cameras: Map<string, PerspectiveCamera> = new Map([
    ['camera', camera],
    ['tankCamera', tank.getCamera()],
]);
const curCamera = { name: 'camera' };
gui.add(curCamera, 'name', ['camera', 'tankCamera']).onChange((key: string) => {
    const cur = cameras.get(key);
    if (cur) {
        stage.setCamera(cur, targetWorldPosi);
    }
});


const posi = new Vector2();
const lookAt = new Vector2();
const targetWorldPosi = new Vector3();
stage.beforeRender = (time: number) => {
    time *= 0.0001;
    curve.getPointAt(time % 1, posi);
    curve.getPointAt((time + 0.001) % 1, lookAt);

    tank.setPosi(new Vector3(posi.x, 0, posi.y));
    tank.setFormer(new Vector3(lookAt.x, 0, lookAt.y));

    target.getWorldPosition(targetWorldPosi);
    tank.rotCannon(targetWorldPosi);
}


new Axis(scene, 10)



let isRender: number = 0;
const CustomGeo = () => {
    const divRef = useRef<HTMLDivElement>(null);
    useEffect(() => {
        const { current } = divRef;
        if (current != null) {
            current.innerHTML = '';
            current.append(renderer.domElement);
            current.append(gui.domElement);
        }
        if (isRender == 0)
            stage.animate();
        isRender++;
    }, []);
    return (
        <div ref={divRef}></div>
    );
};

export default CustomGeo;

function createCamera(fov = 40) {
    return new PerspectiveCamera(fov, window.innerWidth / window.innerHeight, 0.1, 1000);
}